//+------------------------------------------------------------------+
//| 断水流指标 - MT5全功能版本                                            |
//| 包含所有MT4功能：按钮控制、文字显示、垂直线、警报                        |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 11
#property indicator_plots   8

// 6条线 + 2个箭头 = 8个绘图
#property indicator_label1  "Main Line"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrMaroon
#property indicator_width1  3

#property indicator_label2  "Up Line A"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrOrange
#property indicator_width2  3

#property indicator_label3  "Up Line B"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrOrange
#property indicator_width3  2

#property indicator_label4  "Down Line A"
#property indicator_type4   DRAW_LINE
#property indicator_color4  clrLimeGreen
#property indicator_width4  3

#property indicator_label5  "Down Line B"
#property indicator_type5   DRAW_LINE
#property indicator_color5  clrLimeGreen
#property indicator_width5  3

#property indicator_label6  "Signal Line"
#property indicator_type6   DRAW_LINE
#property indicator_color6  clrMagenta
#property indicator_width6  1

#property indicator_label7  "Up Arrow"
#property indicator_type7   DRAW_ARROW
#property indicator_color7  clrOrange
#property indicator_width7  2

#property indicator_label8  "Down Arrow"
#property indicator_type8   DRAW_ARROW
#property indicator_color8  clrLimeGreen
#property indicator_width8  2

// 输入参数 - 完全对应MT4
input int             FastEma     = 13;
input int             SlowEma     = 34;
input int             SignalMA    = 8;
input ENUM_MA_METHOD  SignalMAMode = MODE_EMA;
input int             SigMA       = 8;
input ENUM_MA_METHOD  SigMAMode   = MODE_EMA;

// MT4警报参数
input bool   alertsOn               = true;
input bool   alertsOnCurrent        = false;
input bool   alertsMessage          = true;
input bool   alertsSound            = false;
input bool   alertsEmail            = false;

// MT4文字显示参数
input bool   ShowText               = true;
input string TextDir                = "advanced forecaster Text";
input int    textCorner             = 1;
input int    textXPosition          = 10;
input int    textYPosition          = 10;
input color  upTextColor            = clrBlue;
input color  dnTextColor            = clrRed;
input int    upFontSize             = 12;
input int    dnFontSize             = 12;

// MT4垂直线参数
input bool   verticalLinesVisible   = false;
input bool   linesOnFirst           = false;
input string verticalLinesID        = "advanced forecaster Lines";
input color  verticalLinesUpColor   = clrBlue;
input color  verticalLinesDnColor   = clrRed;
input ENUM_LINE_STYLE verticalLinesStyle = STYLE_SOLID;
input int    verticalLinesWidth     = 2;

// MT4按钮参数
input bool   drawArrows             = true;
input string button_note1           = "------------------------------";
input int    btn_Subwindow          = 0;
input ENUM_BASE_CORNER btn_corner   = CORNER_LEFT_UPPER;
input string btn_text               = "advFo";
input string btn_Font               = "Arial";
input int    btn_FontSize           = 10;
input color  btn_text_ON_color      = clrLime;
input color  btn_text_OFF_color     = clrRed;
input string btn_pressed            = "advFo OFF";
input string btn_unpressed          = "advFo ON";
input color  btn_background_color   = clrDimGray;
input color  btn_border_color       = clrBlack;
input int    button_x               = 850;
input int    button_y               = 20;
input int    btn_Width              = 65;
input int    btn_Height             = 20;
input string soundBT                = "tick.wav";

// 全局变量
bool show_data = true;
string IndicatorName, IndicatorObjPrefix, buttonId;

// 缓冲区 - 完全对应MT4的结构
double sum[];      // 主基础线（深红色）
double sumua[];    // 上升趋势线A（橙色）
double sumub[];    // 上升趋势线B（橙色）
double sumda[];    // 下降趋势线A（绿色）
double sumdb[];    // 下降趋势线B（绿色）
double sig[];      // 信号线（紫色）
double dotu[];     // 上升箭头
double dotd[];     // 下降箭头

// 计算用缓冲区
double temp1[];
double temp2[];
double state[];

// MA句柄
int fastEmaHandle = INVALID_HANDLE;
int slowEmaHandle = INVALID_HANDLE;
int atrHandle = INVALID_HANDLE;

//+------------------------------------------------------------------+
// MT5版本的MAOnArray函数
double MAOnArray_Fixed(const double &array[], int period, ENUM_MA_METHOD ma_method, int shift)
{
   if(period <= 1 || shift < 0) return 0.0;
   
   int arraySize = ArraySize(array);
   if(shift >= arraySize) return 0.0;
   
   if(shift + period > arraySize) period = arraySize - shift;
   if(period <= 0) return 0.0;
   
   double sum_val = 0.0;
   
   switch(ma_method)
   {
      case MODE_SMA:
         for(int i = 0; i < period; i++)
         {
            sum_val += array[shift + i];
         }
         return sum_val / period;
         
      case MODE_EMA:
         {
            double alpha = 2.0 / (period + 1.0);
            double ema = array[shift];
            for(int i = 1; i < period; i++)
            {
               if(shift + i < arraySize)
                  ema = alpha * array[shift + i] + (1.0 - alpha) * ema;
            }
            return ema;
         }
         
      default:
         for(int i = 0; i < period; i++)
         {
            sum_val += array[shift + i];
         }
         return sum_val / period;
   }
}

//+------------------------------------------------------------------+
// MT5版本的PlotPoint函数 - 实现多颜色线条切换
void PlotPoint_Fixed(int i, double &first[], double &second[], double &from[])
{
   if(i < 0 || i >= ArraySize(first) || i >= ArraySize(second) || i >= ArraySize(from))
      return;
   
   bool hasNext1 = (i > 0);
   bool hasNext2 = (i > 1);
   
   if (!hasNext1 || first[i - 1] == EMPTY_VALUE)
   {
      if (!hasNext2 || first[i - 2] == EMPTY_VALUE) 
      {
         first[i] = from[i];
         if(hasNext1) 
            first[i - 1] = from[i - 1];
         second[i] = EMPTY_VALUE;
      }
      else 
      {
         second[i] = from[i];
         if(hasNext1) 
            second[i - 1] = from[i - 1];
         first[i] = EMPTY_VALUE;
      }
   }
   else
   {
      first[i] = from[i];
      second[i] = EMPTY_VALUE;
   }
}

//+------------------------------------------------------------------+
// 按钮创建函数
void createButton(string buttonID, string buttonText, int width, int height, 
                  string font, int fontSize, color bgColor, color borderColor, color txtColor)
{
   ObjectDelete(ChartID(), buttonID);
   ObjectCreate(ChartID(), buttonID, OBJ_BUTTON, btn_Subwindow, 0, 0);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_COLOR, txtColor);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_BGCOLOR, bgColor);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_BORDER_COLOR, borderColor);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_XSIZE, width);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_YSIZE, height);
   ObjectSetString(ChartID(), buttonID, OBJPROP_FONT, font);
   ObjectSetString(ChartID(), buttonID, OBJPROP_TEXT, buttonText);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_FONTSIZE, fontSize);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_SELECTABLE, 0);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_CORNER, btn_corner);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_HIDDEN, 1);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_XDISTANCE, button_x);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_YDISTANCE, button_y);
}

//+------------------------------------------------------------------+
// 生成唯一指标名称
string GenerateIndicatorName(const string target)
{
   string name = target;
   int try_num = 2;
   while(ObjectFind(ChartID(), name) >= 0)
   {
      name = target + " #" + IntegerToString(try_num++);
   }
   return name;
}

//+------------------------------------------------------------------+
// 垂直线绘制
void drawLine(int i, color theColor, const datetime &time[])
{
   if(i < 0 || i >= ArraySize(time)) return;
   
   string name = verticalLinesID + ":" + IntegerToString((int)time[i]);
   
   ObjectDelete(ChartID(), name);
   ObjectCreate(ChartID(), name, OBJ_VLINE, 0, time[i], 0);
   ObjectSetInteger(ChartID(), name, OBJPROP_COLOR, theColor);
   ObjectSetInteger(ChartID(), name, OBJPROP_STYLE, verticalLinesStyle);
   ObjectSetInteger(ChartID(), name, OBJPROP_WIDTH, verticalLinesWidth);
   ObjectSetInteger(ChartID(), name, OBJPROP_BACK, true);
}

//+------------------------------------------------------------------+
// 删除垂直线
void deleteLines()
{
   string lookFor = verticalLinesID + ":";
   int lookForLength = StringLen(lookFor);
   for(int i = ObjectsTotal(ChartID()) - 1; i >= 0; i--)
   {
      string objectName = ObjectName(ChartID(), i);
      if(StringSubstr(objectName, 0, lookForLength) == lookFor) 
         ObjectDelete(ChartID(), objectName);
   }
}

//+------------------------------------------------------------------+
// 文字显示功能
void Commenter(int Dir)
{
   if(ShowText)
   {
      string objName = TextDir;
      ObjectDelete(ChartID(), objName);
      
      // 确保在主图表窗口创建
      bool created = ObjectCreate(ChartID(), objName, OBJ_LABEL, 0, 0, 0);
      
      if(created)
      {
         // 设置位置属性
         ObjectSetInteger(ChartID(), objName, OBJPROP_CORNER, textCorner);
         ObjectSetInteger(ChartID(), objName, OBJPROP_XDISTANCE, textXPosition);
         ObjectSetInteger(ChartID(), objName, OBJPROP_YDISTANCE, textYPosition);
         ObjectSetString(ChartID(), objName, OBJPROP_FONT, "Arial");
         ObjectSetInteger(ChartID(), objName, OBJPROP_BACK, false);  // 前景显示
         ObjectSetInteger(ChartID(), objName, OBJPROP_SELECTABLE, false);
         ObjectSetInteger(ChartID(), objName, OBJPROP_HIDDEN, true);
         
         if(Dir == 1) 
         {
            ObjectSetString(ChartID(), objName, OBJPROP_TEXT, "Buy signal");
            ObjectSetInteger(ChartID(), objName, OBJPROP_FONTSIZE, upFontSize);
            ObjectSetInteger(ChartID(), objName, OBJPROP_COLOR, upTextColor);
         }
         else if(Dir == -1) 
         {
            ObjectSetString(ChartID(), objName, OBJPROP_TEXT, "Sell signal");
            ObjectSetInteger(ChartID(), objName, OBJPROP_FONTSIZE, dnFontSize);
            ObjectSetInteger(ChartID(), objName, OBJPROP_COLOR, dnTextColor);
         }
         
         // 强制刷新图表
         ChartRedraw(ChartID());
      }
   }
}

//+------------------------------------------------------------------+
// 警报管理
void manageAlerts(const datetime &time[])
{
   if(alertsOn)
   {
      int rates_total = ArraySize(state);
      int whichBar = alertsOnCurrent ? rates_total - 1 : rates_total - 2;  // MT5数组索引修正
      
      if(whichBar >= 0 && whichBar - 1 >= 0 && whichBar < rates_total)
      {
         if(state[whichBar] != state[whichBar - 1])
         {
            if(state[whichBar] == 1) doAlert(whichBar, "up", time);
            if(state[whichBar] == -1) doAlert(whichBar, "down", time);
         }
      }
   }
}

//+------------------------------------------------------------------+
// 执行警报
void doAlert(int forBar, string doWhat, const datetime &time[])
{
   static string previousAlert = "nothing";
   static datetime previousTime;
   
   if(forBar >= ArraySize(time)) return;
   
   if(previousAlert != doWhat || previousTime != time[forBar])
   {
      previousAlert = doWhat;
      previousTime = time[forBar];
      
      string symbol = Symbol();
      string message = symbol + " at " + TimeToString(TimeLocal(), TIME_SECONDS) + 
                      " Advanced forecaster trend changed to " + doWhat;
      
      if(alertsMessage) Alert(message);
      if(alertsEmail) SendMail(symbol + " Advanced forecaster", message);
      if(alertsSound) PlaySound("alert2.wav");
   }
}

//+------------------------------------------------------------------+
// 按钮点击处理
void handleButtonClicks()
{
   if(ObjectGetInteger(ChartID(), buttonId, OBJPROP_STATE))
   {
      ObjectSetInteger(ChartID(), buttonId, OBJPROP_STATE, false);
      show_data = !show_data;
      GlobalVariableSet(IndicatorName + "_visibility", show_data ? 1.0 : 0.0);
      
      if(soundBT != "") PlaySound(soundBT);
   }
}

//+------------------------------------------------------------------+
int OnInit()
{
   // 设置缓冲区 - 完全对应MT4结构
   SetIndexBuffer(0, sum, INDICATOR_DATA);      // 主基础线
   SetIndexBuffer(1, sumua, INDICATOR_DATA);    // 上升趋势线A
   SetIndexBuffer(2, sumub, INDICATOR_DATA);    // 上升趋势线B
   SetIndexBuffer(3, sumda, INDICATOR_DATA);    // 下降趋势线A
   SetIndexBuffer(4, sumdb, INDICATOR_DATA);    // 下降趋势线B
   SetIndexBuffer(5, sig, INDICATOR_DATA);      // 信号线
   SetIndexBuffer(6, dotu, INDICATOR_DATA);     // 上升箭头
   SetIndexBuffer(7, dotd, INDICATOR_DATA);     // 下降箭头
   
   // 计算用缓冲区
   SetIndexBuffer(8, temp1, INDICATOR_CALCULATIONS);
   SetIndexBuffer(9, temp2, INDICATOR_CALCULATIONS);
   SetIndexBuffer(10, state, INDICATOR_CALCULATIONS);
   
   // 设置箭头符号
   if(drawArrows) {
      PlotIndexSetInteger(6, PLOT_ARROW, 234);  // MT4的上升箭头符号
      PlotIndexSetInteger(7, PLOT_ARROW, 233);  // MT4的下降箭头符号
   } else {
      PlotIndexSetInteger(6, PLOT_DRAW_TYPE, DRAW_NONE);
      PlotIndexSetInteger(7, PLOT_DRAW_TYPE, DRAW_NONE);
   }
   
   // 创建MA句柄
   fastEmaHandle = iMA(_Symbol, PERIOD_CURRENT, FastEma, 0, MODE_EMA, PRICE_CLOSE);
   slowEmaHandle = iMA(_Symbol, PERIOD_CURRENT, SlowEma, 0, MODE_EMA, PRICE_CLOSE);
   atrHandle = iATR(_Symbol, PERIOD_CURRENT, 20);
   
   if(fastEmaHandle == INVALID_HANDLE || slowEmaHandle == INVALID_HANDLE || atrHandle == INVALID_HANDLE)
   {
      Print("创建指标句柄失败");
      return INIT_FAILED;
   }
   
   // 初始化按钮和界面
   IndicatorName = GenerateIndicatorName(btn_text);
   IndicatorObjPrefix = "__" + IndicatorName + "__";
   buttonId = IndicatorObjPrefix + btn_text;
   
   // 恢复显示状态
   double val;
   if(GlobalVariableGet(IndicatorName + "_visibility", val))
      show_data = val != 0;
   
   // 创建按钮
   createButton(buttonId, btn_text, btn_Width, btn_Height, btn_Font, btn_FontSize, 
               btn_background_color, btn_border_color, btn_text_ON_color);
   
   // 启用图表事件
   ChartSetInteger(ChartID(), CHART_EVENT_MOUSE_MOVE, 1);
   
   return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // 清理资源
   if(fastEmaHandle != INVALID_HANDLE) IndicatorRelease(fastEmaHandle);
   if(slowEmaHandle != INVALID_HANDLE) IndicatorRelease(slowEmaHandle);
   if(atrHandle != INVALID_HANDLE) IndicatorRelease(atrHandle);
   
   // 清理界面对象
   ObjectDelete(ChartID(), buttonId);
   ObjectDelete(ChartID(), TextDir);
   deleteLines();
   ObjectsDeleteAll(ChartID(), IndicatorObjPrefix);
}

//+------------------------------------------------------------------+
// 图表事件处理
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
   handleButtonClicks();
}

//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   if(rates_total < FastEma + SlowEma + SignalMA + SigMA + 10)
      return 0;

   // 处理按钮点击
   handleButtonClicks();

   // 检查数据准备情况
   if(BarsCalculated(fastEmaHandle) < rates_total ||
      BarsCalculated(slowEmaHandle) < rates_total ||
      BarsCalculated(atrHandle) < rates_total)
      return prev_calculated;

   // 获取MA数据
   double fastEmaData[], slowEmaData[], atrData[];
   
   int copied1 = CopyBuffer(fastEmaHandle, 0, 0, rates_total, fastEmaData);
   int copied2 = CopyBuffer(slowEmaHandle, 0, 0, rates_total, slowEmaData);
   int copied3 = CopyBuffer(atrHandle, 0, 0, rates_total, atrData);
   
   if(copied1 <= 0 || copied2 <= 0 || copied3 <= 0)
      return prev_calculated;

   // 计算乘数因子
   double Multiply_Factor_1 = 2.0 / (FastEma + 1.0);
   double Multiply_Factor_2 = 2.0 / (SlowEma + 1.0);
   double Multiply_Factor_3 = Multiply_Factor_1 - Multiply_Factor_2;
   if(MathAbs(Multiply_Factor_3) < 1e-10)
      return prev_calculated;

   // 计算范围
   int start = prev_calculated == 0 ? 0 : prev_calculated - 1;
   
   // 第一阶段：计算temp1[] - MACD差值
   for(int i = start; i < rates_total; i++)
   {
      temp1[i] = fastEmaData[i] - slowEmaData[i];
   }
   
   // 第二阶段：计算temp2[] - MACD信号线
   for(int i = start; i < rates_total; i++)
   {
      temp2[i] = MAOnArray_Fixed(temp1, SignalMA, SignalMAMode, MathMax(0, i - SignalMA + 1));
   }
   
   // 第三阶段：主循环 - 初始化所有缓冲区
   for(int i = start; i < rates_total; i++)
   {
      // 初始化所有显示缓冲区
      sumua[i] = EMPTY_VALUE;
      sumub[i] = EMPTY_VALUE;
      sumda[i] = EMPTY_VALUE;
      sumdb[i] = EMPTY_VALUE;
      dotu[i] = EMPTY_VALUE;
      dotd[i] = EMPTY_VALUE;
      
      // 计算主基础线（sum[]）
      double sumValue = (Multiply_Factor_1 * fastEmaData[i] + slowEmaData[i] - 
                        fastEmaData[i] - Multiply_Factor_2 * slowEmaData[i] + temp2[i]) / Multiply_Factor_3;
      
      if(!MathIsValidNumber(sumValue))
         sumValue = i > 0 ? sum[i-1] : close[i];
         
      sum[i] = sumValue;
   }
   
   // 第四阶段：信号处理和多颜色线条绘制
   for(int i = start; i < rates_total; i++)
   {
      // 计算信号线
      sig[i] = MAOnArray_Fixed(sum, SigMA, SigMAMode, MathMax(0, i - SigMA + 1));
      
      // 状态判断
      state[i] = 0;
      if(sum[i] > high[i]) state[i] = 1;   // 上升趋势
      if(sum[i] < low[i]) state[i] = -1;   // 下降趋势
      
      // 多颜色线条绘制 - 使用PlotPoint逻辑
      if(state[i] == 1)  PlotPoint_Fixed(i, sumua, sumub, sum);   // 上升：橙色线条
      if(state[i] == -1) PlotPoint_Fixed(i, sumda, sumdb, sum);   // 下降：绿色线条
      
      // 箭头显示
      if(i > 0 && state[i] != state[i-1])
      {
         if(state[i] == 1) 
            dotu[i] = sum[i] + atrData[i] / 2;  // 上升箭头
         if(state[i] == -1) 
            dotd[i] = sum[i] - atrData[i] / 2;  // 下降箭头
            
         // 垂直线显示
         if(verticalLinesVisible)
         {
            if(state[i] == 1) drawLine(i, verticalLinesDnColor, time);
            if(state[i] == -1) drawLine(i, verticalLinesUpColor, time);
         }
      }
   }
   
   // 更新按钮状态和显示控制
   if(show_data)
   {
      ObjectSetInteger(ChartID(), buttonId, OBJPROP_COLOR, btn_text_ON_color);
      ObjectSetString(ChartID(), buttonId, OBJPROP_TEXT, btn_unpressed);
   }
   else
   {
      ObjectSetInteger(ChartID(), buttonId, OBJPROP_COLOR, btn_text_OFF_color);
      ObjectSetString(ChartID(), buttonId, OBJPROP_TEXT, btn_pressed);
      
      // 隐藏所有绘图
      for(int p = 0; p < 8; p++)
         PlotIndexSetInteger(p, PLOT_DRAW_TYPE, DRAW_NONE);
      ObjectDelete(ChartID(), TextDir);
      return rates_total;
   }
   
   // 恢复绘图显示
   PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE);
   PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_LINE);
   PlotIndexSetInteger(2, PLOT_DRAW_TYPE, DRAW_LINE);
   PlotIndexSetInteger(3, PLOT_DRAW_TYPE, DRAW_LINE);
   PlotIndexSetInteger(4, PLOT_DRAW_TYPE, DRAW_LINE);
   PlotIndexSetInteger(5, PLOT_DRAW_TYPE, DRAW_LINE);
   if(drawArrows)
   {
      PlotIndexSetInteger(6, PLOT_DRAW_TYPE, DRAW_ARROW);
      PlotIndexSetInteger(7, PLOT_DRAW_TYPE, DRAW_ARROW);
   }
   
   // 文字显示和警报 - 使用最新柱（最右边的柱）
   if(rates_total > 0)
   {
      int latestBar = rates_total - 1;  // MT5中最新数据在数组末尾
      
      // MT4原版的反向逻辑
      if(state[latestBar] == 1) Commenter(-1);  // 上升趋势显示卖出信号
      if(state[latestBar] == -1) Commenter(1);  // 下降趋势显示买入信号
      manageAlerts(time);
   }
   
   return rates_total;
}
//+------------------------------------------------------------------+